# Merise python parser and models generators.
#
# @autor: Patrice Ferlet <metal3d@gmail.com>
# @version 0.0.2
# @licence Gnu/GPL v3

# $Id: sqlite.py 28 2010-04-26 08:59:03Z Metal3d $
# $HeadURL: http://merisier.googlecode.com/svn/tags/0.0.2-alpha1/src/merise/backend/sqlite.py $

import sys,re,os
from datetime import date,time,datetime

class Generator:
    def __init__(self,parser):
        self.parser = parser
        (self.basename, ext) = os.path.splitext(os.path.basename(self.parser.options.filename))
                
    def generate(self):
        """
        Generate SQL file
        """
        sql = "";
        drops = []
        for k,v in self.parser.defs.items():
            drops.append("DROP TABLE IF EXISTS %s;" % k)
            template = "CREATE TABLE %s (\n%s\n);"
            fielddef = []
            primary = []
            fkfield = []
            for field in v:
                if len(field) == 0:
                    continue
                #field has "+" symbole, it's a key
                if re.search('\+',field):
                    field = field.replace('+','')
                    try:
                        #if type is defined we check if it's an auto increment field
                        if len(self.parser.types[k]):
                            for _fielddef in self.parser.types[k]:
                                if _fielddef[0] == field:
                                    if len(_fielddef[1])>0 and _fielddef[1]!='auto':
                                        _type = _fielddef[1]
                                    else:
                                        _type = "INTEGER PRIMARY KEY"

                                #check null value     
                                if _fielddef[2] and _fielddef[4] is not None and not _fielddef[4]:
                                    fkfield.append((_fielddef[0],_fielddef[3]))

                    except:
                        _type = "INTEGER PRIMARY KEY"
                                                        
                    fklines = []
                    for fkf,ref in fkfield:
                        fklines.append('\tFOREIGN KEY (%s) REFERENCES %s(%s) ON DELETE CASCADE' % (fkf, ref, self.parser.keys[ref]))
                                        
                    fielddef.append("\t%s %s" % (field, _type))
                    

                #it's not a key, check definition
                else:
                    _type = "varchar(255) not null"
                    #find type...
                    try:
                        if len(self.parser.types[k]):
                            for _fielddef in self.parser.types[k]:
                                if _fielddef[0] == field:
                                    if len(_fielddef[1]):
                                        _type = _fielddef[1]
                                    else:
                                        _type = "varchar(255)"

                                    # field is foreign key 
                                    if _fielddef[2]==True:
                                        if _type=="auto":
                                            _type = 'int(11)'
                                        if _fielddef[4] is not None and not _fielddef[4]: 
                                            fkfield.append((_fielddef[0],_fielddef[3]))
                            if _fielddef[4] is not None:
                                if not _fielddef[4]:
                                    _type+=' not null'

                    except:
                        _type = "varchar(255) not null"
                    
                    fklines = []
                    
                    done = []
                    for fkf,ref in fkfield:
                        if fkf not in done:
                            fklines.append('\tFOREIGN KEY (%s) REFERENCES %s(%s) ON DELETE CASCADE' % (fkf, ref, self.parser.keys[ref]))
                        done.append(fkf)
                 
                    fielddef.append("\t%s %s" % (field, _type))
            
            if len(fklines):
                fielddef.append(",\n".join(fklines))
                    
            if len(primary):
                fielddef.append("\tPRIMARY KEY(%s)" % ",".join(primary) )

            fielddef = ",\n".join(fielddef);
            sql+= template % (str(k) , fielddef) + "\n\n"

        #it could be fine to know when SQL ha been generated        
        d = datetime.now()

        sql = "PRAGMA foreign_keys=OFF;\n\n%s\n\n%s\nPRAGMA foreign_keys=ON;" % ("\n".join(drops) , sql)
        sql = "/*Generated with %s - %s */\n" % (sys.argv[0], d.strftime("%A, %d. %B %Y %H:%M")) + sql
        
        path=os.path.join( self.parser.options.directory, self.basename+"_sqlite.sql" )
        
        f= open(path,"w")
        f.write(sql)
        f.close()
        
        print path+" generated"
